﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ThermalEquipmentDesign.Model.Condenser.CoolAirR22
{
    public class CoolAirR22Model
    {
        CoolAirR22Result res = new CoolAirR22Result();
        CoolAirR22 condenser;

        /// <summary>
        /// Calculate for air cooled condenser
        /// </summary>
        /// <param name="con">CoolAirR22 object</param>
        /// <returns>CoolAirR22Result object</returns>
        public CoolAirR22Result ImplementCalculation(CoolAirR22 con)
        {
            condenser = con;
            res.dbHeatCapacity = CalculateHeatCapacity();
            res.dbOutAirTemp = CalculateOutAirTemp();
            res.dbAverageTemp = CalculateAverageTemp();
            res.dbLogaritDiffTemp = CalculateLogaritDiffTemp();
            res.dbAirFlow = CalculateAirFlow();
            res.dbVolumeAirFlow = CalculateVolumeAirFlow();
            res.dbCsCoefficient = CalculateCsCoefficient();
            res.dbVaneHeigh = CalculateVaneHeigh();
            res.dbReCoefficient = CalculateReCoefficient();
            res.dbNuCoefficient = CalculateNuCoefficient();
            res.dbConvectionHeatCoefficient = CalculateConvectionHeatCoefficient();
            res.dbVaneArea = CalculateVaneArea();
            res.dbMiddleVaneArea = CalculateMiddleVaneArea();
            res.dbAirHeatCoefficient = CalculateAirHeatCoefficient();
            res.dbInterArea = CalculateInterArea();
            res.dbExterArea = CalculateExterArea();
            res.dbAverageArea = CalculateAverageArea();
            res.dbHeatTransferDensity = CalculateHeatTransferDensity();
            res.dbTotalPipeArea = CalculateTotalPipeArea();
            res.dbTotalPipeLenght = CalculateTotalPipeLenght();
            res.dbTotalPipeNum = CalculateTotalPipeNum();
            res.dbHorizontalPipeNum = CalculateHorizontalPipeNum();
            return res;
        }
        
        /// <summary>
        /// Calculate heat capacity
        /// </summary>
        /// <returns>heat capacity</returns>
        private double CalculateHeatCapacity()
        {
            double Qk = 1.2 * condenser.dbColdProductivity;
            return Math.Round(Qk, 1);
        }

        /// <summary>
        /// Calculate outputted air temperature
        /// </summary>
        /// <returns>outputted air temperature</returns>
        private double CalculateOutAirTemp()
        {
            double t2 = condenser.dbAirTemp + condenser.dbAirDiffTemp;
            return Math.Round(t2, 1);
        }

        /// <summary>
        /// Calculate average temperature
        /// </summary>
        /// <returns>average temperature</returns>
        private double CalculateAverageTemp()
        {
            double tKh = (condenser.dbAirTemp + res.dbOutAirTemp) / 2;
            return Math.Round(tKh, 1);
        }

        /// <summary>
        /// Calculate logarit different temperature
        /// </summary>
        /// <returns>logarit different temperature</returns>
        private double CalculateLogaritDiffTemp()
        {
            double ln = Math.Log((condenser.dbCondensationTemp - condenser.dbAirTemp) / (condenser.dbCondensationTemp - res.dbOutAirTemp));
            double deltat = condenser.dbAirDiffTemp / ln;
            return Math.Round(deltat, 1);
        }

        /// <summary>
        /// Calculate air flow
        /// </summary>
        /// <returns>air flow</returns>
        private double CalculateAirFlow()
        {
            double Mk = res.dbHeatCapacity * Math.Pow(10, 3) / (condenser.dbHeatCapacity * condenser.dbAirDiffTemp);
            return Math.Round(Mk, 2);
        }

        /// <summary>
        /// Calculate volume of air flow
        /// </summary>
        /// <returns>volume of air flow</returns>
        private double CalculateVolumeAirFlow()
        {
            double Mk = res.dbAirFlow / condenser.dbSpecificQuantity;
            return Math.Round(Mk,2);
        }

        /// <summary>
        /// Calculate Cs coefficient
        /// </summary>
        /// <returns>Cs coefficient</returns>
        private double CalculateCsCoefficient()
        {
            double Cs = Math.Pow((condenser.dbHorizontalFinPitch - condenser.dbOriginalDiameter) / (condenser.dbDiagonalFinPitch - condenser.dbOriginalDiameter), 0.2);
            return Math.Round(Cs,2);
        }

        /// <summary>
        /// Calculate heigh of vane
        /// </summary>
        /// <returns>heigh of vane</returns>
        private double CalculateVaneHeigh()
        {
            double l = 0.5 * (condenser.dbVaneDiameter - condenser.dbOriginalDiameter);
            return Math.Round(l,2);
        }

        /// <summary>
        /// Calculate Reynold coefficient
        /// </summary>
        /// <returns>Reynold coefficient</returns>
        private double CalculateReCoefficient()
        {
            double Re = condenser.dbAirSpeed * condenser.dbFinPitch / condenser.dbKinematicViscosity;
            return Math.Round(Re,2);
        }

        /// <summary>
        /// Calculate Nusselt coefficient
        /// </summary>
        /// <returns>Nusselt coefficient</returns>
        private double CalculateNuCoefficient()
        {
            double Nu = condenser.dbCCoefficient * condenser.dbCzCoefficient * res.dbCsCoefficient * Math.Pow(condenser.dbOriginalDiameter / condenser.dbFinPitch, -0.54) * Math.Pow(res.dbVaneHeigh / condenser.dbFinPitch, -0.14) * Math.Pow(res.dbReCoefficient, condenser.dbNCoefficient);
            return Math.Round(Nu,2);
        }

        /// <summary>
        /// Calculate  convection calorific coefficient to air
        /// </summary>
        /// <returns>convection calorific coefficient to air</returns>
        private double CalculateConvectionHeatCoefficient()
        {
            double alpha = res.dbNuCoefficient * condenser.dbHeatConductCoefficient / condenser.dbFinPitch;
            return Math.Round(alpha,2);
        }

        /// <summary>
        /// Calculate area of vane surface
        /// </summary>
        /// <returns>area of vane surface</returns>
        private double CalculateVaneArea()
        {
            double fc = (1 / condenser.dbFinPitch) * (3.14 / 2) * (Math.Pow(condenser.dbVaneDiameter, 2) - Math.Pow(condenser.dbOriginalDiameter, 2)) + (1 / condenser.dbFinPitch) * 3.14 * condenser.dbVaneDiameter * condenser.dbVaneThickness;
            return Math.Round(fc,2);
        }

        /// <summary>
        /// Calculate surface area of middle vane
        /// </summary>
        /// <returns>surface area of middle vane</returns>
        private double CalculateMiddleVaneArea()
        {
            double f0 = condenser.dbOutVaneArea - res.dbVaneArea;
            return Math.Round(f0,2);
        }

        /// <summary>
        /// Calculate calorific coefficient to air
        /// </summary>
        /// <returns>calorific coefficient to air</returns>
        private double CalculateAirHeatCoefficient()
        {
            double arearatio = (res.dbVaneArea / condenser.dbOutVaneArea);
            double middlearearatio = (res.dbMiddleVaneArea / condenser.dbOutVaneArea);
            double ratio = (arearatio * condenser.dbECoefficient * condenser.dbHeatTransferCoefficient + middlearearatio);
            double alpha = res.dbConvectionHeatCoefficient * ratio;
            return Math.Round(alpha,2);
        }

        /// <summary>
        /// Calculate area of internal surface
        /// </summary>
        /// <returns>area of internal surface</returns>
        private double CalculateInterArea()
        {
            double f2 = 3.14 * condenser.dbInterDiameter;
            return Math.Round(f2,2);
        }

        /// <summary>
        /// Calculate area of external surface
        /// </summary>
        /// <returns>area of external surface</returns>
        private double CalculateExterArea()
        {
            double f0 = 3.14 * condenser.dbOriginalDiameter;
            return Math.Round(f0,2);
        }

        /// <summary>
        /// Calculate average area of pipe
        /// </summary>
        /// <returns>average area of pipe</returns>
        private double CalculateAverageArea()
        {
            double fc = (res.dbInterArea + res.dbExterArea) / 2;
            return Math.Round(fc,2);
        }

        /// <summary>
        /// Calculate heat transfer density through total pipe
        /// </summary>
        /// <returns>heat transfer density through total pipe</returns>
        private double CalculateHeatTransferDensity()
        {
            double qc = (res.dbLogaritDiffTemp - condenser.dbDiffTemp) / ((1 / res.dbAirHeatCoefficient) + ((condenser.dbSteelThickness / condenser.dbSteelHeatTransferCoefficient) + (condenser.dbAluThickness / condenser.dbAluHeatTransferCoefficient)) * (condenser.dbOutVaneArea / res.dbAverageArea));
            return Math.Round(qc,2);
        }

        /// <summary>
        /// Calculate area of total pipe
        /// </summary>
        /// <returns>area of total pipe</returns>
        private double CalculateTotalPipeArea()
        {
            double F1 = res.dbHeatCapacity * Math.Pow(10, 3) / res.dbHeatTransferDensity;
            return Math.Round(F1,2);
        }

        /// <summary>
        /// Calculate total of pipe lenght on condenser
        /// </summary>
        /// <returns>total of pipe lenght on condenser</returns>
        private double CalculateTotalPipeLenght()
        {
            double L = res.dbTotalPipeArea / condenser.dbOutVaneArea;
            return Math.Round(L,2);
        }

        /// <summary>
        /// Calculate total of pipe
        /// </summary>
        /// <returns>total of pipe</returns>
        private double CalculateTotalPipeNum()
        {
            double n = res.dbTotalPipeLenght / condenser.dbPipeLenght;
            return Math.Round(n,0);
        }

        /// <summary>
        /// Calculate the number of pipe on horizontal
        /// </summary>
        /// <returns>Number of pipe on horizontal</returns>
        private double CalculateHorizontalPipeNum()
        {
            double n1 = res.dbTotalPipeNum / condenser.dbAirPipeNume;
            return Math.Round(n1,0);
        }
    }
}
